#============================================================
#	Simple Platform Controller
#============================================================
#  简单的平台角色控制器
# * 添加这个子节点到 KinematicBody2D 下即可使用
#============================================================
# @datetime: 2022-2-28 12:03:06
#============================================================
class_name SimplePlatformController
extends MoveController


signal jumped


## 在这个时间内按下跳跃，在落在地面上后自动进行跳跃（输入缓冲）
const BUFFER_TIME = 0.1
## 离开地面后，在这个时间内仍可以进行跳跃（土狼时间）
const GRACE_TIME = 0.2


export var jump_height : float = 0
export var gravity : float = 0
## 判定为落下的要求超出的速度
export var determine_fall : float = 10.0

var jump_enabled : bool = true
var gravity_enabled : bool = true


# 缓冲跳跃计时器
var __buffer_jump_timer__ := Timer.new()
# 土狼时间计时器
var __grace_timer__ := Timer.new()

# 跳跃高度
var __jump_height__ : float = 0.0


#============================================================
#   Set/Get
#============================================================
func get_direction() -> Vector2:
	return __direction__

func set_property_data(data: Dictionary):
	for prop in data:
		if prop in self:
			set(prop, data[prop])

##  在土狼时间内可以跳跃
func is_can_jump():
	return __grace_timer__.time_left > 0

func is_jumping():
	return __last_velocity__.y < 0

func is_falling():
	return __last_velocity__.y > determine_fall


#============================================================
#   内置
#============================================================
func _ready():
	__buffer_jump_timer__.wait_time = BUFFER_TIME
	__buffer_jump_timer__.one_shot = true
	__buffer_jump_timer__.connect("timeout", self, "set", ['_jump', false])
	add_child(__buffer_jump_timer__)
	
	__grace_timer__.wait_time = GRACE_TIME
	__grace_timer__.one_shot = true
	add_child(__grace_timer__)


#============================================================
#   自定义
#============================================================
#(override)
func _move(delta: float):
	# 重力
	if gravity_enabled:
		motion_velocity.y += gravity * delta
	else:
		motion_velocity.y = 0
	
	# 碰到天花板
	if __host__.is_on_ceiling() and motion_velocity.y < 0:
		motion_velocity.y = 0
	
	# 开始跳跃
	if __buffer_jump_timer__.time_left > 0:
		if (__host__.is_on_floor() 
			or __grace_timer__.time_left > 0
		):
			_jump()
	else:
		# 土狼时间
		if __host__.is_on_floor():
			__grace_timer__.start(GRACE_TIME)
	
	__last_velocity__ = __host__.move_and_slide(motion_velocity, Vector2.UP)
	motion_velocity = __last_velocity__
	motion_velocity.x = 0


#(override)
func move_direction(direction: Vector2):
	move_left_right(direction.x)
	if direction.y < 0:
		jump(direction.y * __jump_height__)


#(override)  
func move_vector(velocity: Vector2):
	if move_enabled:
		_update_state(Vector2(sign(velocity.x), 0))
		motion_velocity.x = velocity.x
	if velocity.y < 0:
		jump(velocity.y)


##  控制跳跃
func _jump():
	motion_velocity.y = -__jump_height__
	__buffer_jump_timer__.stop()
	__grace_timer__.stop()
	emit_signal("jumped")


##  更改方向
func change_direction(dir: float):
	update_direction(Vector2(dir, 0))


##  左右移动
## @left_right  
func move_left_right(left_right: float):
	if move_enabled:
		_update_state(Vector2(left_right, 0))
		motion_velocity.x = left_right * __move_speed__


##  跳跃
## @height  跳跃高度
## @force  强制跳跃
func jump(height: float = INF, force: bool = false):
	# Jump
	if jump_enabled:
		__jump_height__ = (height if height != INF else jump_height)
		if force:
			_jump()
		else:
			__buffer_jump_timer__.start()

